package com.demomaster.quickcompat.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.TextView;

import java.util.HashMap;
import java.util.Map;


/**
 * 悬浮按钮
 * Created
 */
public abstract class QuickFloatingService extends Service {
    private static final String TAG = "QDFloatingService";
    private WindowManager windowManager;
    private Map<View, ViewPositionInfo> viewPositionInfoMap;
    //public WindowManager.LayoutParams layoutParams;

    /**
     * 需要 SYSTEM_ALERT_WINDOW权限
     */
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "服务启动" + this.getClass().getName());
        viewPositionInfoMap = new HashMap<>();
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        onCreateView(getApplicationContext(), windowManager);
    }

    public abstract void onCreateView(Context context, WindowManager windowManager);

    private void updateViewPosition(ViewPositionInfo viewPositionInfo) {
        if (viewPositionInfo != null) {
            WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) viewPositionInfo.getView().getLayoutParams();
            if (layoutParams != null) {
                layoutParams.x = (int) viewPositionInfo.getX();
                layoutParams.y = (int) viewPositionInfo.getY();
                viewPositionInfo.update();
                viewPositionInfoMap.put(viewPositionInfo.getView(), viewPositionInfo);
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void updateViewLayout(View view, int width, int height) {
        WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) view.getLayoutParams();
        layoutParams.width = width;
        layoutParams.height = height;
        windowManager.updateViewLayout(view, layoutParams);
    }

    /**
     * 设置窗口高度
     *
     * @param height
     */
    public void setHeight(View view, int height) {
        ViewPositionInfo viewPositionInfo = viewPositionInfoMap.get(view);
        if (viewPositionInfo != null) {
            WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) view.getLayoutParams();
            layoutParams.height = height;
            //updateLayoutParams(view);
            windowManager.updateViewLayout(view, layoutParams);
            updateViewPositionInfo(view);
        }
    }

    /**
     * 设置窗口宽度
     *
     * @param width
     */
    public void setWidth(View view, int width) {
        ViewPositionInfo viewPositionInfo = viewPositionInfoMap.get(view);
        if (viewPositionInfo != null) {
            WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) view.getLayoutParams();
            layoutParams.width = width;
            windowManager.updateViewLayout(view, layoutParams);
            updateViewPositionInfo(view);
        }
    }

    private void updateViewPositionInfo(View view) {
        if(viewPositionInfoMap.containsKey(view)){
            ViewPositionInfo viewPositionInfo = viewPositionInfoMap.get(view);
            if (viewPositionInfo != null) {
                viewPositionInfo.update();
                viewPositionInfoMap.put(view, viewPositionInfo);
            }
        }else {
            ViewPositionInfo viewPositionInfo = new ViewPositionInfo(view);
            viewPositionInfoMap.put(view, viewPositionInfo);
        }
    }

    public void setPosition(View view, Point point) {
        WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) view.getLayoutParams();
        layoutParams.x = point.x;
        layoutParams.y = point.y;
        view.setLayoutParams(layoutParams);
    }

    public static class FloatingOnTouchListener implements View.OnTouchListener{
        private int x;
        private int y;
        private long startTime = 0;
        private long endTime = 0;
        private boolean isclick;
        private boolean hasTouchDown;//处理拦截了按下事件的情况

        View targetView;//目标控件（位置要移动的控件）
        WindowManager windowManager;

        public FloatingOnTouchListener(View targetView) {
            this.targetView = targetView;
            windowManager = (WindowManager) targetView.getContext().getSystemService(WINDOW_SERVICE);
            //targetView.getViewTreeObserver().addOnGlobalLayoutListener(this);
        }

        @Override
        public boolean onTouch(View view, MotionEvent event) {
            //System.out.println("执行顺序down");
            Log.d(TAG, "view1 ="+targetView.getLayoutParams().width+","+targetView.getLayoutParams().height+targetView);

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();
                    isclick = false;//当按下的时候设置isclick为false
                    startTime = System.currentTimeMillis();
                    hasTouchDown = true;
                    //System.out.println("执行顺序down");
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (!hasTouchDown) {
                        x = (int) event.getRawX();
                        y = (int) event.getRawY();
                        isclick = false;//当按下的时候设置isclick为false
                        startTime = System.currentTimeMillis();
                        hasTouchDown = true;
                    }
                    isclick = true;//当按钮被移动的时候设置isclick为true,就拦截掉了点击事件

                    int nowX = (int) event.getRawX();
                    int nowY = (int) event.getRawY();
                    int movedX = nowX - x;
                    int movedY = nowY - y;
                    x = nowX;
                    y = nowY;
                    if (targetView != null) {
                        if (targetView.getLayoutParams() instanceof WindowManager.LayoutParams) {
                            WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) targetView.getLayoutParams();
                            layoutParams.x = layoutParams.x + movedX;
                            layoutParams.y = layoutParams.y + movedY;
                            Log.e(TAG,"onTouch:" + layoutParams.width + "," + layoutParams.height);
                            windowManager.updateViewLayout(targetView, layoutParams);
                        } else if (targetView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
                            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) targetView.getLayoutParams();
                            layoutParams.leftMargin = layoutParams.leftMargin + movedX;
                            layoutParams.topMargin = layoutParams.topMargin + movedY;
                            Log.e(TAG,"onTouch2:" + layoutParams.width + "," + layoutParams.height);
                            targetView.setLayoutParams(layoutParams);
                        } else {
                            Log.e(TAG,"onTouch:" + targetView.getLayoutParams().getClass().getName());
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    endTime = System.currentTimeMillis();
                    //当从点击到弹起小于半秒的时候,则判断为点击,如果超过则不响应点击事件
                    isclick = ((endTime - startTime) > 0.15 * 1000L);
                    hasTouchDown = false;
                    break;
                case MotionEvent.ACTION_CANCEL:
                    hasTouchDown = false;
                    break;
                default:
                    break;
            }
            return isclick;
        }

//        @Override
//        public void onRelease(Object self) {
//            targetView = null;
//            windowManager = null;
//        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        viewPositionInfoMap.clear();
        Log.e(TAG, "onDestroyService " + this.getClass().getName());
        //QuickEvent.getDefault().post(new EventMessage(0,this.getClass(),1));
    }

    public void addView(View view, WindowManager.LayoutParams layoutParams, boolean touchAble, int positionX, int positionY) {
        addView(view, layoutParams, touchAble, touchAble, positionX, positionY);
    }

    public void addView(View view, WindowManager.LayoutParams layoutParams, boolean touchAble, boolean dragable, int positionX, int positionY) {
        if (view == null || view.getParent() != null) {
            throw new RuntimeException("contentView is null");
        }
        if (dragable) {
            view.setOnTouchListener(new FloatingOnTouchListener(view));
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;//TYPE_APPLICATION_OVERLAY;
        } else {
            //layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
            layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }
        layoutParams.format = PixelFormat.RGBA_8888;
        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        if (!touchAble) {
            layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        } else {
            layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        }
        layoutParams.x = positionX;
        layoutParams.y = positionY;
        //updateLayoutParams();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.canDrawOverlays(this)) {
                windowManager.addView(view, layoutParams);
            }
        } else {
            windowManager.addView(view, layoutParams);
        }
        //Log.d(TAG, "addView ="+view.getLayoutParams().width+","+view.getLayoutParams().height);
        updateViewPositionInfo(view);
        //解决多个view添加时 有些view宽高WRAP_CONTENT变成MATCH_PARENT的问题
        view.post(new Runnable() {
            @Override
            public void run() {
                for (View view1 : viewPositionInfoMap.keySet()){
                    view1.getLayoutParams().height = view1.getHeight();
                    view1.getLayoutParams().width = view1.getWidth();
                    Log.d(TAG, "view1 ="+view1.getLayoutParams().width+","+view1.getLayoutParams().height);
                }
            }
        });
        //处理view位置大小变更
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //updateViewPositionInfo(view);
                for (View view1 : viewPositionInfoMap.keySet()){
                    updateViewPositionInfo(view1);
                    //Log.d(TAG, "更新view2 ="+view1.getLayoutParams().width+","+view1.getLayoutParams().height);
                }
            }
        });
    }

    public void removeView(View view) {
        // setIsShowing(false);
        if (view != null && view.getParent() != null) {
            if (windowManager != null) {
                windowManager.removeView(view);
            }
        }
    }

    public void dissmissWindow() {
        getApplicationContext().stopService(new Intent(getApplicationContext(), this.getClass()));
    }
}
